package lendingbooks.activities;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;

import lendingbooks.book.Book;
import lendingbooks.book.BookManager;
import lendingbooks.utils.ServiceCallException;
import lendingbooks.utils.ServiceManager;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TabHost;
import android.widget.TextView;
import android.widget.Toast;

import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.AsyncFacebookRunner.RequestListener;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
import com.facebook.android.Util;

public class SearchBookActivity extends Activity {

	private enum Status {
		OFFLINE, LOGGED, NO_LOGED
	}

	private Status status = null;

	private Facebook facebook = new Facebook("141686359258739");
	private Book book;
	private boolean bFacebookLogin = false;
	private boolean bBookHasBeenSearched = false;
	private SharedPreferences mPrefs;
	private AsyncFacebookRunner asyncFacebookRunner;

	// UI
	private Button facebookButton;
	private Button facebookLogOutButton;
	private Button searchButton;
	private EditText isbnEditText;
	private Button scanButton;
	private TextView textViewTitle;
	private TextView textViewIsbn;
	private TextView textViewAuthorsText;
	private Button addButton;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		_InitUIElements();
		addButton.setVisibility(View.INVISIBLE);
		asyncFacebookRunner = new AsyncFacebookRunner(facebook);
		scanButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				_ScanIsbnBarCode();// Manage on onActivityResult
			}
		});

		searchButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				_SearchISBN();
			}
		});

		facebookButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				_FacebookAuth();
			}
		});

		facebookLogOutButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				_FacebookLogOut();
			}
		});
		// Once the tab and the activity is create LendingbooksActivity calls
		// checkFacebookLogin
	}

	@Override
	public void onResume() {
		super.onResume();
		facebook.extendAccessTokenIfNeeded(this, null);
	}

	public void checkFacebookLogin() {
		Log.d("SearchBookActivity", "checkFacebookLogin");
		final ProgressDialog dialogCheckingFacebook = ProgressDialog.show(this,
				"", "Checking log in... Please wait...", true);
		final Handler handlerCheckingFacebook = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				Bundle b = msg.getData();
				boolean userIsLogged = b.getBoolean("userIsLogged");
				Log.d("SearchBookActivity", "userIsLogged msg[" + userIsLogged
						+ "]");
				if (userIsLogged) {
					_LoginLendingBooksWithFacebookUser();
				}
				dialogCheckingFacebook.dismiss();
			}
		};

		Thread task = new Thread() {
			@Override
			public void run() {
				mPrefs = getPreferences(MODE_PRIVATE);
				String access_token = mPrefs.getString("access_token", null);
				long expires = mPrefs.getLong("access_expires", 0);
				boolean userIsLogged = false;
				if (access_token != null) {
					facebook.setAccessToken(access_token);
				}
				if (expires != 0) {
					facebook.setAccessExpires(expires);
				}
				if (facebook.isSessionValid()) {
					userIsLogged = true;
				}
				Log.d("SearchBookActivity", "userIsLogged run [" + userIsLogged
						+ "]");
				Message message = new Message();
				Bundle b = new Bundle();
				b.putBoolean("userIsLogged", userIsLogged);
				message.setData(b);
				handlerCheckingFacebook.sendMessage(message);
			}
		};
		task.start();
	}

	private void _LoginLendingBooksWithFacebookUser() {

		Log.d("LENDINGBOOKS _FacebookAuth", "onComplete");
		final ProgressDialog dialog = ProgressDialog.show(this, "",
				"Connecting to lending books...", true);

		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				setUIToLoggedStatus();
				dialog.dismiss();
			}
		};

		Thread loginInLendingBooks = new Thread() {
			@Override
			public void run() {
				try {
					String sMe = facebook.request("me");
					String token = facebook.getAccessToken();
					Long expires = facebook.getAccessExpires();

					JSONObject json = Util.parseJson(sMe);
					String name = json.getString("name");
					String id = json.getString("id");

					SharedPreferences.Editor editor = mPrefs.edit();
					editor.putString("access_token", token);
					editor.putLong("access_expires", expires);
					editor.commit();

					ServiceManager sm = new ServiceManager();
					HashMap<String, String> params = new HashMap<String, String>();
					params.put("fbAccessToken", token);
					params.put("fbUserId", id);
					sm.POST(ServiceManager.SERVICE.FACEBOOK_SERVER_LOGIN,
							params);
					((LendingBooksApplication) getApplication())
							.setFbUserId(id);
					((LendingBooksApplication) getApplication())
							.setFbAccessToken(token);
					((LendingBooksApplication) getApplication())
							.setFbUserName(name);
				} catch (MalformedURLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (ServiceCallException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (FacebookError e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				handler.sendEmptyMessage(0);
			}
		};
		loginInLendingBooks.start();

	}

	private void setUIToLoggedStatus() {
		TabHost tabHost = ((LendingBooksApplication) getApplication())
				.getTabHost();
		tabHost.getTabWidget().getChildAt(1).setVisibility(View.VISIBLE);
		tabHost.getTabWidget().getChildAt(2).setVisibility(View.VISIBLE);
		facebookButton.setVisibility(View.GONE);
		facebookLogOutButton.setVisibility(View.VISIBLE);
		bFacebookLogin = true;
		if (bBookHasBeenSearched) {
			addButton.setVisibility(View.VISIBLE);
			addButton.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					_SaveCopy();
				}
			});
		}
	}

	private void _FacebookAuth() {
		facebook = new Facebook("141686359258739");
		facebook.authorize(this, new String[] { "email" },
				new DialogListener() {
					@Override
					public void onFacebookError(FacebookError e) {
						Log.d("LENDINGBOOKS onFacebookError", e.getMessage());
					}

					@Override
					public void onCancel() {
						Log.d("LENDINGBOOKS onFacebookError", "onCancel");
					}

					@Override
					public void onComplete(Bundle values) {
						_LoginLendingBooksWithFacebookUser();
					}

					@Override
					public void onError(DialogError e) {
						Log.d("LENDINGBOOKS onFacebookError", "onError");
					}
				});
	}

	private void _FacebookLogOut() {
		asyncFacebookRunner.logout(this, new RequestListener() {
			@Override
			public void onComplete(String response, Object state) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onIOException(IOException e, Object state) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onFileNotFoundException(FileNotFoundException e,
					Object state) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onMalformedURLException(MalformedURLException e,
					Object state) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onFacebookError(FacebookError e, Object state) {
				// TODO Auto-generated method stub
			}
		});
		_CleanFacebookLogin();
	}

	private void _CleanFacebookLogin() {
		TabHost tabHost = ((LendingBooksApplication) getApplication())
				.getTabHost();
		tabHost.getTabWidget().getChildAt(1).setVisibility(View.GONE);
		tabHost.getTabWidget().getChildAt(2).setVisibility(View.GONE);
		facebookButton.setVisibility(View.VISIBLE);
		facebookLogOutButton.setVisibility(View.GONE);
		bFacebookLogin = false;
		SharedPreferences.Editor editor = mPrefs.edit();
		editor.remove("access_token");
		editor.remove("access_expires");
		editor.commit();
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent intend) {
		super.onActivityResult(requestCode, resultCode, intend);
		Log.d("LENDINGBOOKS onActivityResult", "requestCode_" + requestCode);
		if (requestCode == 0) {
			if (resultCode == RESULT_OK) {
				String contents = intend.getStringExtra("SCAN_RESULT");
				isbnEditText.setText(contents);
				_SearchISBN();
			}
		} else {
			facebook.authorizeCallback(requestCode, resultCode, intend);
		}

	}

	private void _SearchISBN() {
		final ProgressDialog dialog = ProgressDialog.show(
				SearchBookActivity.this, "", "Loading. Please wait...", true);
		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				dialog.dismiss();
				boolean ok = (Boolean) msg.getData().getSerializable("ok");
				if (ok) {
					book = (Book) msg.getData().getSerializable("book");
					_PrintBookSearched(book);
				} else {
					String errMessage = (String) msg.getData().getSerializable(
							"errMessage");
					showErrMessage("Err[" + errMessage + "]");
				}
			}
		};

		Thread searchBook = new Thread() {
			@Override
			public void run() {
				BookManager bm = new BookManager();
				String isbn = isbnEditText.getText().toString();
				Book book = null;
				boolean ok = true;
				String errMessage = "";
				try {
					book = bm.findByIsbn(isbn);
				} catch (ServiceCallException e) {
					e.printStackTrace();
					ok = false;
					errMessage = e.getMessage();
				}

				Message message = new Message();
				Bundle b = new Bundle();
				b.putSerializable("book", book);
				b.putBoolean("ok", ok);
				b.putString("errMessage", errMessage);
				message.setData(b);

				handler.sendMessage(message);

			}
		};
		searchBook.start();
	}

	private void _PrintBookSearched(Book p_book) {
		if (p_book.getId() == null) {
			Log.d("LENDINGBOOKS SearchBookActivity",
					" _PrintSearchedBook_p_book==null");
			textViewTitle.setText(R.string.isbnNotFound);
		} else {
			textViewTitle.setText(p_book.getTitle());
			textViewIsbn.setText(p_book.getIsbn());
			textViewAuthorsText.setText(p_book.getAuthorsText());
			bBookHasBeenSearched = true;
			if (bFacebookLogin) {
				addButton.setVisibility(View.VISIBLE);
				addButton.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						_SaveCopy();
					}
				});
			}
		}
	}

	public void showErrMessage(String message) {
		Context context = getApplicationContext();
		int duration = Toast.LENGTH_SHORT;
		Toast toast = Toast.makeText(context, message, duration);
		toast.show();
	}

	private void _SaveCopy() {
		final ProgressDialog dialog = ProgressDialog.show(this, "",
				"Adding to your library... Please wait...", true);

		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				((LendingBooksApplication) getApplication())
						.setMyLibraryChanged(true);
				dialog.dismiss();
			}
		};

		Thread saveCopy = new Thread() {
			@Override
			public void run() {
				HashMap<String, String> params = new HashMap<String, String>();
				params.put("book_id", book.getId().toString());
				ServiceManager sm = new ServiceManager();
				try {
					sm.PUT(ServiceManager.SERVICE.ADD_TO_MY_LIBRARY, params);
				} catch (ServiceCallException e) {
					e.printStackTrace();
				}

				handler.sendEmptyMessage(0);
			}
		};
		saveCopy.start();
	}

	private void _ScanIsbnBarCode() {
		try {
			Intent intent = new Intent("com.google.zxing.client.android.SCAN");
			intent.setPackage("com.google.zxing.client.android");
			startActivityForResult(intent, 0);
		} catch (ActivityNotFoundException e) {
			Context context = getApplicationContext();
			CharSequence text = "App barcode scaner must be instaled !";
			int duration = Toast.LENGTH_SHORT;
			Toast toast = Toast.makeText(context, text, duration);
			toast.show();
			Intent goToMarket = new Intent(Intent.ACTION_VIEW)
					.setData(Uri
							.parse("market://details?id=com.google.zxing.client.android"));
			startActivity(goToMarket);
		}
	}

	private void _InitUIElements() {
		setContentView(R.layout.search);
		searchButton = (Button) findViewById(R.id.isbnSearchButton);
		isbnEditText = (EditText) findViewById(R.id.isbnEditText);
		textViewTitle = (TextView) findViewById(R.id.textViewTitle);
		textViewIsbn = (TextView) findViewById(R.id.textViewIsbn);
		textViewAuthorsText = (TextView) findViewById(R.id.textViewAuthorsText);
		scanButton = (Button) findViewById(R.id.scanButton);
		facebookButton = (Button) findViewById(R.id.facebookButton);
		facebookLogOutButton = (Button) findViewById(R.id.facebookLogOutButton);
		addButton = (Button) findViewById(R.id.addButton);
	}

}
